package com.yuxl.admin.common.security.service;

import com.yuxl.admin.common.security.config.SecurityProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.ReactiveStringRedisTemplate;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.time.Duration;

@Slf4j
@Service
@RequiredArgsConstructor
public class RedisTokenService {

    // 创建日志记录器

    // 注入 ReactiveStringRedisTemplate 用于操作 Redis
    private final ReactiveStringRedisTemplate redisTemplate;
    private final SecurityProperties securityProperties;


    // 保存令牌到 Redis，设置过期时间为 3600 秒（1小时）
    public Mono<Boolean> saveToken(String username, String token) {
        return redisTemplate.opsForValue().set(securityProperties.getRedisPrefix()+username, token, Duration.ofSeconds(3600))
                .doOnSuccess(result -> log.debug("Token saved successfully for user: {}", username))
                .doOnError(error -> log.error("Error saving token for user: {}", username, error));
    }

    // 从 Redis 中获取令牌
    public Mono<String> getToken(String username) {
        return redisTemplate.opsForValue().get(securityProperties.getRedisPrefix()+username)
                .doOnSuccess(result -> log.debug("Token retrieved successfully for user: {}", username))
                .doOnError(error -> log.error("Error retrieving token for user: {}", username, error));
    }

    // 从 Redis 中删除令牌
    public Mono<Boolean> deleteToken(String username) {
        return redisTemplate.opsForValue().delete(securityProperties.getRedisPrefix()+username)
                .doOnSuccess(result -> log.debug("Token deleted successfully for user: {}", username))
                .doOnError(error -> log.error("Error deleting token for user: {}", username, error));
    }

    // 检查令牌是否存在于 Redis 中
    public Mono<Boolean> tokenExists(String username, String token) {
        return redisTemplate.opsForValue().get(securityProperties.getRedisPrefix()+username)
                .map(storedToken -> storedToken.equals(token))
                .defaultIfEmpty(false);
    }

    // 新增方法：检查令牌是否存在且未过期
    public Mono<String> getValidToken(String username) {
        String key = securityProperties.getRedisPrefix() + username;
        return redisTemplate.opsForValue().get(key)
                .doOnSuccess(token -> {
                    if (token != null) {
                        log.debug("Found valid token for user: {}", username);
                    } else {
                        log.debug("No valid token found for user: {}", username);
                    }
                })
                .doOnError(error -> log.error("Error retrieving token for user: {}", username, error));
    }

    // 更新令牌的过期时间
    public Mono<Boolean> refreshTokenExpiration(String username, String token) {
        String key = securityProperties.getRedisPrefix() + username;
        return redisTemplate.opsForValue().set(key, token, Duration.ofSeconds(3600))
                .doOnSuccess(result -> log.debug("Token expiration refreshed for user: {}", username))
                .doOnError(error -> log.error("Error refreshing token expiration for user: {}", username, error));
    }
}
